package net.oschina.arvin.multi.field.sort;

/**
 * @author Arvin
 * @time 2017/10/30 22:51
 */
public abstract class AbstractSortItem implements SortItem {

    /** 是否是升序排序， 默认是升序 */
    protected boolean asc = true;

    public boolean isAsc() {
        return asc;
    }

    public void setAsc(boolean asc) {
        this.asc = asc;
    }

    /**
     * 比较两个值， 比较过程为：
     * 1. 如果两个都是null则分拿回0
     * 2. 如果第一个为null，第二个不为null则返回-1
     * 3. 如果第一个不为null，第二个为null则返回1
     * 4. 如果实现了 Comparable 则使用这个比较
     * 5. 没有实现的话，看看是否是原始类型（int, long, byte, short, boolean, char, double, float）
     *
     * @param v1 第一个值
     * @param v2 第二个值
     * @return
     */
    @SuppressWarnings({"unchecked"})
    protected int compareValue(Object v1, Object v2) {
        int ret = 0;
        if (v1 == null && v2 == null) {
            ret = 0;
        } else if (v1 != null && v2 == null) {
            ret = 1;
        } else if (v1 == null) {
            ret = -1;
        } else {
            Class<?> dataType = v1.getClass();
            if (v1.getClass() == v2.getClass()) {
                if (Comparable.class.isAssignableFrom(dataType)) {
                    ret = ((Comparable) v1).compareTo(v2);
                } else {
                    if (dataType == int.class) {
                        ret = ((Integer) v1).compareTo((Integer) v2);
                    } else if (dataType == long.class) {
                        ret = ((Long) v1).compareTo((Long) v2);
                    } else if (dataType == short.class) {
                        ret = ((Short) v1).compareTo((Short) v2);
                    } else if (dataType == float.class) {
                        ret = ((Float) v1).compareTo((Float) v2);
                    } else if (dataType == double.class) {
                        ret = ((Double) v1).compareTo((Double) v2);
                    } else if (dataType == boolean.class) {
                        ret = ((Boolean) v1).compareTo((Boolean) v2);
                    } else if (dataType == char.class) {
                        ret = String.valueOf(v1).compareTo(String.valueOf(v2));
                    } else if (dataType == byte.class) {
                        ret = ((Byte) v1).compareTo((Byte) v2);
                    } else {
                        throw new IllegalArgumentException("无法比较的属性，v1=" + v1.getClass().getName() + ", v2=" + v2.getClass().getName());
                    }
                }
            } else {
                // 类型都不一样，无法比较，抛异常
                throw new IllegalArgumentException("值类型不一致，无法比较，v1=" + v1.getClass().getName() + ", v2=" + v2.getClass().getName());
            }
        }

        return isAsc() ? ret : reversedCompareRet(ret);
    }

    /**
     * 反转比较结果
     *
     * @param compareRet 比较结果
     */
    protected int reversedCompareRet(int compareRet) {
        return compareRet == 0 ? 0 : compareRet == -1 ? 1 : -1;
    }
}
